package com.ldk.base.framework.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import org.apache.commons.lang.StringUtils;

public class FileUtil {
	
	/**
	 * 获取文件名的扩展名
	 * @param fileName
	 * @return 包括"."的扩展名称如: ".png"
	 */
	public static String getFileExtention(String fileName){
		if(StringUtils.isEmpty(fileName))
			return "";
		if(!StringUtils.contains(fileName, '.')){
			return "";
		}
		if(fileName.lastIndexOf('.') > 0){
			return fileName.substring(fileName.lastIndexOf('.'));
		}
		return "";
	}
	
	/**
	 * 创建文件夹
	 * @param folder 文件名称
	 * @return
	 */
	public static Boolean createDir(String folder){
		File fileDir = new File(folder);
		if(!fileDir.exists()){
			try{

				return fileDir.mkdirs();
			}
			catch(Exception e){
				return false;
			}
		}
		return true;
	}
	/**
	 * 保存文件
	 * @param folder 文件存放的文件路径
	 * @param fileName 文件名称包括扩展名
	 * @param data 文件数据
	 * @return true 成功 false 失败
	 */
	public static Boolean saveFile(String folder, String fileName, byte[] data){
		if(StringUtils.isEmpty(folder) || 
		   StringUtils.isEmpty(fileName)){
			return false; 
		}
		if(!createDir(folder)){
			return false;
		}
		try{
			String savePath = folder.replace("\\", "/");
			if(!StringUtils.endsWith(savePath, "/")){
				savePath += "/";
			}
			savePath += fileName;
			FileOutputStream stream = new FileOutputStream(savePath);
			stream.write(data);
			stream.flush();
			stream.close();
			
			return true;
		}
		catch(Exception e){
			
		}
		return false;
	}
	
	/**
	 * 删除文件
	 * @param filePath 文件完整路径
	 * @return
	 */
	public static Boolean deleteFile(String filePath){
		try{
			File file = new File(filePath);
			if(file.isDirectory()){
				String[] children = file.list();
				for(String child:children){
					deleteFile(child);
				}
			}
			if(file.exists()){
				return file.delete();
			}
		}
		catch(Exception e){
			e.printStackTrace();
		}
		return false;
	}
	
	/**
	 * 删除文件夹及文件夹下所有文件
	 * @param floderPath 文件夹完整路径
	 * @return 
	 */
	public static Boolean deleteFolder(String folderPath){
		try{

			File folder = new File(folderPath);
			if(folder.exists()){
				deleteFile(folderPath);
				return true;
			}
		}
		catch(Exception e){
			
		}
		return false;
	}
	
	/**
	 * 获取文件夹所有的文件列表
	 * @param folderPath
	 * @return
	 */
	public static String[] getFiles(String folderPath){
		try{

			File folder = new File(folderPath);
			if(folder.isDirectory()){
				return folder.list();
			}
		}
		catch(Exception e){
			
		}
		return null;
	}
	
	/**
	 * zip压缩文件夹(压缩文件名称以文件夹名称作为名称)
	 * @param sourceFilePath 文件夹路径
	 * @return
	 */
	public static Boolean zip(String sourceFilePath){
		if(StringUtils.isEmpty(sourceFilePath)){
			return false;
		}
		File target = null;
        File source = new File(sourceFilePath);
        if (source.exists()) {
            // 压缩文件名=源文件名.zip
            String zipName = source.getName() + ".zip";
            target = new File(source.getParent(), zipName);
            if (target.exists()) {
                target.delete(); // 删除旧的文件
            }
            FileOutputStream fos = null;
            ZipOutputStream zos = null;
            try {
                fos = new FileOutputStream(target);
                zos = new ZipOutputStream(new BufferedOutputStream(fos));
                // 添加对应的文件Entry
                addEntry("/", source, zos);
                
                return true;
                
            } catch (IOException e) {
                throw new RuntimeException(e);
            } finally {
                closeQuietly(zos, fos);
            }
        }
        return false;
	}
	
	/**
	 * zip压缩文件夹
	 * @param sourceFilePath 文件夹路径
	 * @param zipFileName 压缩文件名称
	 * @return
	 */
	public static Boolean zip(String sourceFilePath, String zipFileName){
		if(StringUtils.isEmpty(sourceFilePath)){
			return false;
		}
		File target = null;
        File source = new File(sourceFilePath);
        if (source.exists()) {
            String zipName = String.format("%s.zip", zipFileName);
            target = new File(source.getParent(), zipName);
            if (target.exists()) {
                target.delete(); // 删除旧的文件
            }
            FileOutputStream fos = null;
            ZipOutputStream zos = null;
            try {
                fos = new FileOutputStream(target);
                zos = new ZipOutputStream(new BufferedOutputStream(fos));
                // 添加对应的文件Entry
                addEntry("/", source, zos);
                
                return true;
                
            } catch (IOException e) {
                throw new RuntimeException(e);
            } finally {
                closeQuietly(zos, fos);
            }
        }
        return false;
	}
	
	/**
     * 扫描添加文件Entry
     * 
     * @param base
     *            基路径
     * 
     * @param source
     *            源文件
     * @param zos
     *            Zip文件输出流
     * @throws IOException
     */
    private static void addEntry(String base, File source, ZipOutputStream zos)
            throws IOException {
        // 按目录分级，形如：/aaa/bbb.txt
        String entry = base + source.getName();
        if (source.isDirectory()) {
            for (File file : source.listFiles()) {
                // 递归列出目录下的所有文件，添加文件Entry
                addEntry(entry + "/", file, zos);
            }
        } else {
            FileInputStream fis = null;
            BufferedInputStream bis = null;
            try {
                byte[] buffer = new byte[1024 * 10];
                fis = new FileInputStream(source);
                bis = new BufferedInputStream(fis, buffer.length);
                int read = 0;
                zos.putNextEntry(new ZipEntry(entry));
                while ((read = bis.read(buffer, 0, buffer.length)) != -1) {
                    zos.write(buffer, 0, read);
                }
                zos.closeEntry();
            } finally {
                closeQuietly(bis, fis);
            }
        }
    }
	/**
	 * 关闭一个或多个流对象
	 * @param closeables
	 * @throws IOException
	 */
	public static void close(Closeable...closeables) throws IOException{
		if(closeables != null){
			for(Closeable closeable :closeables){
				if(closeable != null){
					closeable.close();
				}
			}
		}
	}
	/**
	 * 关闭一个或多个流对象
	 * @param closeables
	 * @throws IOException
	 */
	public static void closeQuietly(Closeable...closeables){
		try{
			
			close(closeables);
		}
		catch(IOException e){
			
		}
	}
}
